package com.tgpms.web.earlierStage.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tgpms.common.Result;
import com.tgpms.exception.ExceptionExplain;
import com.tgpms.util.Common;
import com.tgpms.web.earlierStage.dao.ObsInfoMapper;
import com.tgpms.web.earlierStage.dao.UsersAuthorityMapper;
import com.tgpms.web.earlierStage.entity.ObsInfo;
import com.tgpms.web.earlierStage.service.ObsInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @ClassName ObsInfoServiceImpl
 * @Description TODO
 * @Author GUAN
 * @Date 2019-12-24 11:29
 * @Version 1.0
 * @return
 **/
@Service
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, rollbackFor = Exception.class)
public class ObsInfoServiceImpl implements ObsInfoService {

	@Autowired
	private ObsInfoMapper obsInfoMapper;
	@Autowired
	private UsersAuthorityMapper usersAuthorityMapper;
	@Autowired
	private RedisTemplate<String, Object> redis;

	//新增项目查询树形组织机构接口
	@Override
	public List<Object> selObsInfoToAdd(String userId) {
		List<Object> list = new ArrayList<Object>();
		List<ObsInfo> obsList = obsInfoMapper.getUserObsCodes(userId);

		List<ObsInfo> rootList = new ArrayList<ObsInfo>();
		//声明一个map，用来过滤已操作过的数据
		Map<String,String> map = new HashMap<String, String>(obsList.size());
		//获取根节点
		Stream<ObsInfo> strObsList = obsList.stream();
		strObsList = strObsList.filter(c -> c.getParentId()==null);
		strObsList.forEach(c -> {
			rootList.add(c);
			map.put(c.getObsCode(),c.getParentId());//当前节点code和父节点id
		});
		final List<ObsInfo> obsinfos = obsList;
		rootList.forEach(c -> {
			JSONObject tempJson = (JSONObject) JSONObject.toJSON(c);
			List<JSONObject> childList = getChild(c, map, obsinfos);
			if(childList!=null && childList.size()>0) {
				tempJson.put("children", childList);
			}
			list.add(tempJson);
		});
		return list;
	}

	@Override
	public Result addObsInfo(ObsInfo obsInfo, Result result) {
		QueryWrapper<ObsInfo> queryWrapper = new QueryWrapper<ObsInfo>();
		queryWrapper.eq("OBS_NO", obsInfo.getObsNo());
		if(obsInfoMapper.selectList(queryWrapper).size()>0) {
			result.setSuccess(false);
			result.setMsg(ExceptionExplain.ERROR_BY_INSERT_REPETITION.getExplain());
			return result;
		}
		obsInfo.setObsCode(Common.fromDateFormats()+ UUID.randomUUID().toString().replaceAll("-", "").toUpperCase());
		obsInfo.setInsertDate(new Date());
		obsInfo.setRowstamp(obsInfo.getObsCode());
		int i = obsInfoMapper.insert(obsInfo);
		if(i==1) {
			redis.opsForValue().set("obsList","");
			result.setMsg(ExceptionExplain.SUCCESS_BY_INSERT.getExplain());
			result.setData(obsInfo.getObsCode());
		}else {
			result.setSuccess(false);
			result.setMsg(ExceptionExplain.ERROR_BY_INSERT.getExplain());
		}
		return result;
	}

	@Override
	public Result updateObsInfo(ObsInfo obsInfo, Result result) {
		obsInfo.setModifyDate(new Date());
		int i = obsInfoMapper.updateById(obsInfo);
		if(i==1) {
			redis.opsForValue().set("obsList","");
			result.setMsg(ExceptionExplain.SUCCESS_BY_UPDATE.getExplain());
		}else {
			result.setSuccess(false);
			result.setMsg(ExceptionExplain.ERROR_BY_UPDATE.getExplain());
		}
		return result;
	}

	@Override
	public Result deleteObsInfo(String obsCode, Result result) {
		QueryWrapper<ObsInfo> queryWrapper = new QueryWrapper<ObsInfo>();
		queryWrapper.eq("PARENT_ID", obsCode);
		List<ObsInfo> obsInfos = obsInfoMapper.selectList(queryWrapper);
		int i = 0;
		if (obsInfos != null && obsInfos.size() > 0) {
			for (ObsInfo obsInfo: obsInfos) {
				i = obsInfoMapper.deleteById(obsInfo.getObsCode());
			}
		}
		i = obsInfoMapper.deleteById(obsCode);
		if(i==1) {
			redis.opsForValue().set("obsList","");
			result.setMsg(ExceptionExplain.SUCCESS_BY_DELETE.getExplain());
		}else {
			result.setSuccess(false);
			result.setMsg(ExceptionExplain.ERROR_BY_DELETE.getExplain());
		}
		return result;
	}

	//查询组织架构树形
	@Override
	public List<JSONObject> selObsInfo(String usersId,String obsCode,String obsNo) {
		List<JSONObject> list = new ArrayList<JSONObject>();
		List<String> codeList = new ArrayList<String>();
		if(usersId!=null) {
			//查询用户组织权限
			codeList = usersAuthorityMapper.getCodeByUserid(usersId);
			if(codeList==null || codeList.size()==0) {
				return list;
			}
		}
		List<ObsInfo> rootList = new ArrayList<ObsInfo>();
		//查询所有记录
		List<ObsInfo> obsList = new ArrayList<ObsInfo>();
		if(Common.isEmpty(redis.opsForValue().get("obsList"))) {
			QueryWrapper<ObsInfo> queryWrapper = new QueryWrapper<ObsInfo>(); 
			queryWrapper.orderByAsc("OBS_NO");
			obsList = obsInfoMapper.selectList(queryWrapper);
			redis.opsForValue().set("obsList",obsList);
		}else {
			obsList = JSON.parseArray(redis.opsForValue().get("obsList").toString(),ObsInfo.class);
		}

		if(obsList!=null && obsList.size()>0) {
			//过滤用户权限
			if(codeList!=null && codeList.size()>0) {
				final List<String> codes = codeList;
				List<ObsInfo> obsinfos = new ArrayList<ObsInfo>();
				obsinfos = obsList.stream().filter(c -> codes.contains(c.getObsCode()))
						.collect(Collectors.toList());
				obsList = obsinfos;
			}
			//声明一个map，用来过滤已操作过的数据
			Map<String,String> map = new HashMap<String, String>(obsList.size());
			//获取根节点
			Stream<ObsInfo> strObsList = obsList.stream();
			if(obsCode!=null) {
				strObsList = strObsList.filter(c -> c.getObsCode().equals(obsCode));
			}else {
				strObsList = strObsList.filter(c -> c.getParentId()==null);
			}
			strObsList.forEach(c -> { 
				rootList.add(c);
				map.put(c.getObsCode(),c.getParentId());//当前节点code和父节点id
			});
			final List<ObsInfo> obsinfos = obsList;
			rootList.forEach(c -> {
				JSONObject tempJson = (JSONObject) JSONObject.toJSON(c);
				List<JSONObject> childList = getChild(c, map, obsinfos);
				if(childList!=null && childList.size()>0) {
					tempJson.put("children", childList);
				}
				list.add(tempJson);
			});
		}
		return list;
	}

	private List<JSONObject> getChild(ObsInfo root,Map<String,String> map,List<ObsInfo> obsList){
		List<JSONObject> list = new ArrayList<JSONObject>();
		obsList.stream()
		.filter(c -> !map.containsKey(c.getObsCode()))
		.filter(c -> c.getParentId()!=null)
		.filter(c -> c.getParentId().equals(root.getObsCode()))
		.forEach(c ->{
			map.put(c.getObsCode(),c.getParentId());//当前节点code和父节点id
			JSONObject tempJson = (JSONObject) JSONObject.toJSON(c);
			List<JSONObject> childList = getChild(c, map, obsList);
			if(childList!=null && childList.size()>0) {
				tempJson.put("children", childList);
			}
			list.add(tempJson);
		});
		return list;
	}

}
